package com.xxl.job.admin.util;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * @author hujj
 * @version 1.0
 * @date 2021/6/2/002 14:02
 */
@Component
public class ApplicationContextHelper implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ApplicationContextHelper.applicationContext = applicationContext;
    }

    public static ApplicationContext getApplicationContext(){
        return  ApplicationContextHelper.applicationContext;
    }

    public static<T> T getBean(Class<T> targetClz){
        T beanInstance = null;
        //优先按type查
        try {
            beanInstance = (T) applicationContext.getBean(targetClz);
        }catch (Exception e){
        }
        //按name查
        if(beanInstance == null){
            String simpleName = targetClz.getSimpleName();
            //首字母小写
            simpleName = Character.toLowerCase(simpleName.charAt(0)) + simpleName.substring(1);
            beanInstance = (T) applicationContext.getBean(simpleName);
        }
        if(beanInstance == null){
            new RuntimeException("PLAT_ERROR: Component " + targetClz + " can not be found in Spring Container");
        }
        return beanInstance;
    }
    public static Object getBean(String claz){
        return ApplicationContextHelper.applicationContext.getBean(claz);
    }

    /**
     * 获取当前请求Controller所执行的方法
     * @param request  {@link HttpServletRequest} 请求
     * @return  返回当前执行的方法
     */
    public static Method getControllerExecuteMethod(HttpServletRequest request) throws Exception {
        RequestMappingHandlerMapping handlerMapping=(RequestMappingHandlerMapping) applicationContext
                .getBean("requestMappingHandlerMapping");
        //RequestMappingHandlerMapping是对应url和处理类方法的一个类
        HandlerExecutionChain handlerChain=handlerMapping.getHandler(request);;
        //通过处理链找到对应的HandlerMethod类
        HandlerMethod handler=(HandlerMethod) handlerChain.getHandler();
        //HandlerMethod中有bean和method
//        Object bean=handler.getBean();//处理请求的类
        Method method=handler.getMethod();//处理请求的方法
        return method;
    }
}
